718C - Sasha and Array - CodeForces Solution


data structures math matrices *2300

Please click on ads to support us..

C++ Code:

#include <bits/stdc++.h>
#define _c const
#define _r register
#define ALL(x) x.begin(), x.end()
using namespace std;
_c int64_t mod = 1e9 + 7;
struct mat {
  int64_t _[2][2];
  mat(int64_t _00 = 0LL, int64_t _01 = 0LL, int64_t _10 = 0LL, int64_t _11 = 0LL) {
    _[0][0] = _00 % mod, _[0][1] = _01 % mod, _[1][1] = _11 % mod, _[1][0] = _10 % mod;
  }
  ~mat() {}
  int64_t *operator[](size_t x) { return this->_[x]; }
  friend mat operator+(mat x, mat y) {
    return mat((x[0][0] + y[0][0]) % mod, (x[1][0] + y[1][0]) % mod,
               (x[0][1] + y[0][1]) % mod, (x[1][1] + y[1][1]) % mod);
  }
  friend mat operator*(mat x, mat y) {
    return mat ((x[0][0] * y[0][0] + x[0][1] * y[1][0]) % mod, (x[0][0] * y[0][1] + x[0][1] * y[1][1]) % mod,
                (x[1][0] * y[0][0] + x[1][1] * y[1][0]) % mod, (x[1][0] * y[0][1] + x[1][1] * y[1][1]) % mod);
  }
  friend mat operator+=(mat &x, mat y) { return x = x + y; }
  friend mat operator*=(mat &x, mat y) { return x = x * y; }
};
inline mat qick_power(mat x, int32_t y) {
  mat ans = mat(1, 0, 0, 1);
  while (y) {
    if (y & 1) { ans *= x; }
    x *= x;
    y >>= 1;
  }
  return ans;
}
class Segment_tree {
private:
  struct Node {
    size_t left, right, length;
    mat laz_mul, value;
    Node *left_son, *right_son;
    Node () {
      left = right = length = 0U;
      laz_mul = value = mat(1, 0, 0, 1);
      left_son = right_son = nullptr;
    } 
    ~Node () {
      if (left_son != nullptr) { left_son->~Node(); }
      if (right_son != nullptr) { right_son->~Node(); }
      delete this;
    }
    
    inline void build(size_t left, size_t right, int32_t *val) {
      this->left = left, this->right = right, this->length = right - left + 1;
      if (left == right) {
        this->value = qick_power(mat(0, 1, 1, 1), val[left] + 1);
        return void (0);
      }
      size_t mid = left + (right - left >> 1);
      this->left_son = new Node, this->left_son->build(left, mid, val);
      this->right_son = new Node, this->right_son->build(mid + 1, right, val);
      this->value = this->left_son->value + this->right_son->value;
    }
    inline void laz_push_down() {
      this->left_son->laz_mul *= this->laz_mul;
      this->left_son->value *= this->laz_mul;
      this->right_son->laz_mul *= this->laz_mul;
      this->right_son->value *= this->laz_mul;
      this->laz_mul = mat (1, 0, 0, 1);
    }
    inline void modify_mul(size_t left, size_t right, mat &val) {
      if (right < this->left || this->right < left) { return void (0); }
      if (left <= this->left && this->right <= right) {
        this->laz_mul *= val;
        this->value *= val;
        return void (0);
      }
      laz_push_down();
      this->left_son->modify_mul(left, right, val);
      this->right_son->modify_mul(left, right, val);
      this->value = this->left_son->value + this->right_son->value;
    }
    inline mat query(size_t left, size_t right) {
      if (right < this->left || this->right < left) { return mat(); }
      if (left <= this->left && this->right <= right) { return this->value; }
      laz_push_down();
      return this->left_son->query(left, right) + this->right_son->query(left, right);
    }
  };
protected:
  Node *tree;

public:
  inline void build(size_t n, int32_t *val) {
    tree = new Node;
    tree->build(1U, n, val);
  }
  inline void modify_add(size_t left, size_t right, int32_t val) {
    mat _val = qick_power(mat(0, 1, 1, 1), val);
    tree->modify_mul(left, right, _val);
  }
  inline int64_t query(size_t left, size_t right) {
    return tree->query(left, right)[0][0];
  }
} tree;
int32_t n, m;
int32_t inp[100005];
inline void solve() {
  scanf("%d %d", &n, &m);
  for (size_t i = 1; i <= n; i++) { scanf("%d", inp + i); }
  tree.build(n, inp);
  while (m--) {
    size_t opt, l, r;
    scanf("%u %u %u", &opt, &l, &r);
    if (opt == 1) {
      int32_t val;
      scanf("%d", &val);
      tree.modify_add(l, r, val);
    }
    if (opt == 2) {
      printf("%lld\n", tree.query(l, r));
    }
  }
}
signed main() {
  solve();
  return 0;
} 
	  		 	  		 				    			 	 	 	


Comments

Submit
0 Comments
More Questions

Lexical Sorting Reloaded
1514A - Perfectly Imperfect Array
580A- Kefa and First Steps
1472B- Fair Division
996A - Hit the Lottery
MSNSADM1 Football
MATCHES Playing with Matches
HRDSEQ Hard Sequence
DRCHEF Doctor Chef
559. Maximum Depth of N-ary Tree
821. Shortest Distance to a Character
1441. Build an Array With Stack Operations
1356. Sort Integers by The Number of 1 Bits
922. Sort Array By Parity II
344. Reverse String
1047. Remove All Adjacent Duplicates In String
977. Squares of a Sorted Array
852. Peak Index in a Mountain Array
461. Hamming Distance
1748. Sum of Unique Elements
897. Increasing Order Search Tree
905. Sort Array By Parity
1351. Count Negative Numbers in a Sorted Matrix
617. Merge Two Binary Trees
1450. Number of Students Doing Homework at a Given Time
700. Search in a Binary Search Tree
590. N-ary Tree Postorder Traversal
589. N-ary Tree Preorder Traversal
1299. Replace Elements with Greatest Element on Right Side
1768. Merge Strings Alternately